package sequentiell;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;


public class Graph {
	
	String relationSymbol = "->";
	
	
	private static Map<Integer,ArrayList<Integer>> relations = new HashMap<Integer,ArrayList<Integer>>();
	private Map<Integer,Integer> values = new HashMap<Integer,Integer>();
	private static ArrayList<Integer> nodes = new ArrayList<Integer>();
	
	//the list from the parser
	private ArrayList<Integer> nodesP = new ArrayList<Integer>();
	private ArrayList<Integer> valuesP = new ArrayList<Integer>();
	private ArrayList<String> relationsP = new ArrayList<String>();
	
	
	/**
	 * 
	 * @param filePath where the graph XML-document is saved
	 * @throws Exception 
	 */
	public Graph(String filePath) throws Exception{
		
		Parser parser = new Parser(filePath);
		nodesP = parser.getNodes();
		valuesP = parser.getValues();
		relationsP = parser.getRelations();
		
		//transfer argument-nodes in local nodes-set 
		for(int i = 0;i<nodesP.size();i++){
			Graph.nodes.add(nodesP.get(i));
			this.values.put(nodesP.get(i), valuesP.get(i));
			
//			System.out.println("sortedValues "+i+": ("+valuesP.get(i)+","+nodesP.get(i)+")");
		}
		
		//transfer argument-relations in local relations-map
		String[] temp;
		int src, dst;
		ArrayList<Integer> curr = new ArrayList<Integer>();
		//iterate over all argument-relations
		for(int i = 0;i<relationsP.size();i++){
			temp = relationsP.get(i).split(relationSymbol);
			src = new Integer(temp[0]).intValue();
			dst = new Integer(temp[1]).intValue();
			
			//if target-relations just has this source, put it in the destination-ArrayList
			if(relations.containsKey(src)){
				relations.get(src).add(dst);
//				System.out.println("dst "+dst+" added in src "+src+", also dstSize= "+relations.get(src).size());
				continue;
			}
			//else create a new entry for the target-relations
			curr.add(dst);
			relations.put(src,curr);
//			System.out.println("new src "+src+" added with dst "+dst+", also dstSize= "+curr.size());
			curr = new ArrayList<Integer>();
		}
	}
	
	/**
	 * 
	 * @return all relations of the graph
	 */
	public Map<Integer,ArrayList<Integer>> getRelations(){
		return relations;
	}
	
	/**
	 * 
	 * @return all nodes of the graph
	 */
	public ArrayList<Integer> getNodes(){
		return nodes;
	}
	
	/**
	 * 
	 * @param i the position of the node
	 * @return the node at the position i in the list of the nodes
	 */
	public int getNode(int i){
		return nodes.get(i);
	}
	
	/**
	 * 
	 * @return all values of all nodes
	 */
	public Map<Integer,Integer> getValues(){
		return values;
	}
	
	/**
	 * calculate all predecessors of the given node
	 * @param node
	 * @return a mesh with all predecessors
	 */
	public static Mesh Pre(int node){
		Mesh erg = new Mesh();
		
		ArrayList<Integer> actualRel;
		int actualNode;
		for(int i=0;i<nodes.size();i++){
			actualNode = nodes.get(i);
			actualRel = relations.get(actualNode);
			if(actualRel==null)
				continue;
			if(actualRel.contains(node))
				erg.add(actualNode);
		}
		return erg;
	}

	/**
	 * calculate all predecessors of the given mesh
	 * @param mesh
	 * @return a mesh with all predecessors
	 */
	public static Mesh Pre(Mesh mesh){
		Mesh erg = new Mesh(),
			temp;
		for(int i=0;i<mesh.size();i++){
			temp = Pre(mesh.get(i));
			for(int j=0;j<temp.size();j++){
				erg.add(temp.get(j));
			}
		}
		return erg;
	}
}
